﻿#include "facade.h"
#include "ui_facade.h"

Facade::Facade(QWidget *parent) :
    BaseFacade(parent),
    ui(new Ui::Facade)
{
    ui->setupUi(this);

    note=nullptr;
    note2=nullptr;
    popup=nullptr;
    searchBox=nullptr;
    udpReceiver=nullptr;

    feature=new Feature(this);
    connect(feature,&Feature::say,this,&Facade::say);

    QDir cacheDir(Location::cacheLocation);
    if(!cacheDir.exists())
        cacheDir.mkpath(Location::cacheLocation);

    QDir dataDir(Location::dataLocation);
    if(!dataDir.exists())
        dataDir.mkpath(Location::dataLocation);

    startUp();
}

Facade::~Facade()
{
    if(feature->config.isReceiver)
        endReceiver();

    delete ui;
}

void Facade::startUp()
{
    feature->startUp();

    if(feature->config.isAdvanced)
        setAcceptDrops(true);
    setSkin();

    defPos.setX(d_width - DEF_WID);
    defPos.setY(200);
    moveDefPos();
    if(feature->config.isReceiver)
        startReceiver();

    cmdStore.connectStorage(TD_REF_CMD);
    createMenu();

    autoHideId=startTimer(AUTOHIDE_INTERVAL);
    connect(this,&TransFacade::trayStateChanged,this,&Facade::onTrayStateChanged);

    createTray(QIcon(":/app.ico"));
    if(feature->config.isAdvanced)
        tray->setToolTip(QString::number(SP_VER) + QStringLiteral(" - SinglePoint 运行中【高级模式】"));
    else
        tray->setToolTip(QString::number(SP_VER) + QStringLiteral(" - SinglePoint 运行中"));
}

void Facade::onTrayStateChanged()
{
    killTimer(autoHideId);
    autoHideId=startTimer(AUTOHIDE_INTERVAL);
}

void Facade::startReceiver()
{
    udpReceiver=new BaseUdpReceiver;
    connect(udpReceiver,&BaseUdpReceiver::received,this,&Facade::receivedMessage);
    connect(&udpRecvThread,&QThread::finished,udpReceiver,&QObject::deleteLater);
    udpReceiver->moveToThread(&udpRecvThread);
    udpRecvThread.start();

    restReceiver=new BaseRestReceiver;
    connect(restReceiver,&BaseRestReceiver::received,this,&Facade::receivedObject);
    connect(&restRecvThread,&QThread::finished,restReceiver,&QObject::deleteLater);
    restReceiver->moveToThread(&restRecvThread);
    restRecvThread.start();
}

void Facade::endReceiver()
{
    udpRecvThread.quit();
    udpRecvThread.wait();

    restRecvThread.quit();
    restRecvThread.wait();
}

void Facade::receivedMessage(const QByteArray &data)
{
    parseCommand(QString(data));
}

void Facade::receivedObject(const QJsonObject &json)
{

}

void Facade::parseCommand(const QString &cmd)
{
    QString request=cmd;
    if(request.isEmpty())
        return;

    int code=cmdStore.parseCommand(request);
    switch (code) {
    case CMD_NULL:
        say(QStringLiteral("不识别的命令"));
        break;
    case CMD_RELOAD_MENU:
        break;
    case CMD_SCREEN_SHOT:
        feature->util_shotScreen();
        break;
    case CMD_EXIT:
        qApp->quit();
        break;
    case CMD_ACT_PREFIX:
        commander.execute(code,cmdStore.getParams());
        break;
    default:
        commander.execute(code,cmdStore.getArgs());
        break;
    }
}

void Facade::timerEvent(QTimerEvent *event)
{
    int id=event->timerId();
    if(id == autoHideId)
    {
        if(!isActiveWindow() && isVisible())
            this->hide();
    }
}

void Facade::setSkin()
{
    switch (getSkin()) {
    case sk_gre:
        skin_gre;
        break;
    case sk_blu:
        skin_blu;
        break;
    case sk_pik:
        skin_pik;
        break;
    default:
        skin_blu;
        break;
    }
}

void Facade::dragEnterEvent(QDragEnterEvent *event)
{
    if(feature->form == Form_None || feature->isWorking)
        return;

    //如果为文件，则支持拖放
    if(event->mimeData()->hasFormat("text/uri-list"))
        event->acceptProposedAction();
}

void Facade::dropEvent(QDropEvent *event)
{
    if(feature->form == Form_None)
        return;

    QList<QUrl> urls = event->mimeData()->urls();
    if(urls.isEmpty())
        return;

    QString fileName=urls.first().toLocalFile();
    feature->dropFile(fileName);
}

void Facade::contextMenuEvent(QContextMenuEvent *)
{
    if(menu != nullptr)
        menu->exec(QCursor::pos());
}

void Facade::keyPressEvent(QKeyEvent *event)
{
    if(event->modifiers() == Qt::AltModifier && event->key()==Qt::Key_1)
        showNote();
    else if(event->modifiers() == Qt::AltModifier && event->key()==Qt::Key_2)
        showNote2();
    else if(event->modifiers() == Qt::AltModifier && event->key()==Qt::Key_F2)
        showSearchBox();
    // else if(event->modifiers() == Qt::AltModifier && event->key()==Qt::Key_W)
    //    showThroughPanel();
    //    else if(event->modifiers() == Qt::AltModifier && event->key()==Qt::Key_P)
    //    util_grubScreen();
    else
    {
        switch(event->key())
        {
        case Qt::Key_Home:
            moveDefPos();
            break;
        case Qt::Key_F1:
            if(QFile::exists(README))
                QDesktopServices::openUrl(QUrl::fromLocalFile(README));
            break;
        case Qt::Key_F3:
            invokeCalc();
            break;
        case Qt::Key_J:
            feature->util_verifyMD5();
            break;
        case Qt::Key_K:
            feature->util_verifySHA1();
            break;
        case Qt::Key_L:
            feature->util_stringLength();
            break;
        case Qt::Key_U:
            feature->util_generateUuid();
            break;
        case Qt::Key_M:
            feature->util_magnet();
            break;
        case Qt::Key_B:
            feature->util_baiduPan();
            break;
        case Qt::Key_W:
            feature->util_webThrough();
            break;
            //        case Qt::Key_P:
            //          util_grubRect();
            //          break;
        case Qt::Key_Backspace:
            feature->util_reset();
            break;
        }
    }
}

void Facade::mouseDoubleClickEvent(QMouseEvent *)
{
    feature->util_mouseDoubleClickEvent();
}

void Facade::createMenu()
{
    menu=new SmartMenu(this);
    menu->setConfigurator(feature->config);
    connect(menu,&SmartMenu::reloadMenu,this,&Facade::rebuildMenu);
    connect(menu,&SmartMenu::say,this,&Facade::say);
    connect(menu,&SmartMenu::invokeProp,this,&Facade::invokeProp);
    connect(menu,&SmartMenu::changeSkin,this,&Facade::changeSkin);
    menu->generateMenu();
}

void Facade::rebuildMenu()
{
    feature->config.reload();
    menu->clear();
    menu->disconnect();
    connect(menu,&SmartMenu::reloadMenu,this,&Facade::rebuildMenu);
    connect(menu,&SmartMenu::say,this,&Facade::say);
    connect(menu,&SmartMenu::invokeProp,this,&Facade::invokeProp);
    connect(menu,&SmartMenu::changeSkin,this,&Facade::changeSkin);
    menu->generateMenu();
    say("菜单已重建");
}

void Facade::invokeProp(int propId)
{
    switch (propId) {
    case ID_NOTE:
        showNote();
        break;
    case ID_NOTE2:
        showNote2();
        break;
    case ID_SEARCHBOX:
        showSearchBox();
        break;
    case ID_CALC:
        invokeCalc();
        break;
    }
}

void Facade::showMessage(const QString &title, const QString &message)
{
    tray->showMessage(title,message);
}

void Facade::changeSkin(int skinId)
{
    switch (skinId) {
    case sk_blu:
        putSkin(sk_blu);
        skin_blu;
        break;
    case sk_pik:
        putSkin(sk_pik);
        skin_pik;
        break;
    case sk_gre:
        putSkin(sk_gre);
        skin_gre;
        break;
    }
}

void Facade::showSearchBox()
{
    if(searchBox==nullptr)
    {
        searchBox=new SearchBox(this);
        connect(searchBox,&SearchBox::sendCmd,this,&Facade::parseCommand);

        searchBox->move(d_width /2 - 200,50);
    }
    searchBox->show();
}

void Facade::showNote()
{
    if(note==nullptr)
        note=new Note(this);

    note->setUserLand(userLand);
    note->firstLoad();
    note->move(300,100);
    note->show();
}

void Facade::showNote2()
{
    if(note2==nullptr)
        note2=new Note2(this);

    note2->setUserLand(userLand);
    note2->firstLoad();
    note2->move(400,200);
    note2->show();
}

void Facade::invokeCalc()
{
    QDesktopServices::openUrl(QUrl(Calc));
}

void Facade::pop(const QString &title, const QString &content)
{
    if(popup == nullptr)
        popup=new Popup(this);
    popup->showMe(title,content);
}

void Facade::say(const QString &word, unsigned sec)
{
    Torus *tor=new Torus;
    tor->setStyle(getSkin());
    curPos=this->pos();
    tor->move(curPos.x() - 450,curPos.y() - 100 );
    tor->display(word,sec);
}
